{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "import matplotlib.pyplot as plt\n",
    "from numpy import *\n",
    "import math\n",
    "from numpy.ma import array\n",
    "\n",
    "def loadDataSet():\n",
    "    dataMat = []; labelMat = []\n",
    "    fr = open('testSet.txt')\n",
    "    for line in fr.readlines():\n",
    "        #print(line)\n",
    "        lineArr = line.strip().split()\n",
    "        #print(lineArr)\n",
    "        # 每行前两个值是X1和X2，第三个值是标签，为了方便计算将X0预设为1\n",
    "        dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])\n",
    "        labelMat.append(int(lineArr[2]))\n",
    "    return dataMat,labelMat\n",
    " \n",
    "def sigmoid(inX):\n",
    "    return 1.0/(1+exp(-inX))\n",
    " \n",
    "# 梯度计算\n",
    "# dataMatIn是2维Numpy数组，每列对应不同特征，每行是一个训练样本\n",
    "# 现在里面有X0，X1,X2的100*3的矩阵\n",
    "def gradAscent(dataMatIn, classLabels):\n",
    "    dataMatrix = mat(dataMatIn)             #转化为Numpy矩阵\n",
    "    labelMat = mat(classLabels).transpose() #由行向量转化为列向量,矩阵的转置\n",
    "    m,n = shape(dataMatrix)#m=100,n=3\n",
    "    # 步长\n",
    "    alpha = 0.001\n",
    "    # 迭代次数\n",
    "    maxCycles = 500\n",
    "    weights = ones((n,1))\n",
    "    for k in range(maxCycles):              #heavy on matrix operations\n",
    "        # 每一个样本乘上一个回归系数\n",
    "        h = sigmoid(dataMatrix*weights)     #矩阵相乘，h是一个列向量 1*100\n",
    "        error = (labelMat - h)              #vector subtraction\n",
    "        weights = weights + alpha * dataMatrix.transpose()* error #按差值方向调整回归系数\n",
    "# 这里dataMatrix.transpose()* error就是当前对应的梯度\n",
    "    return weights"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "matrix([[ 4.03864782],\n",
       "        [ 0.45575756],\n",
       "        [-0.60168588]])"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dataArr,labelMat=loadDataSet()\n",
    "weights=gradAscent(dataArr, labelMat)\n",
    "weights"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "data的形状： (100, 3)\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "#将分类给画出来，画出最佳的拟合直线  \n",
    "def plotBestFit(weights):  \n",
    "    \"\"\" \n",
    "    :param weights: 最佳回归系数数组 \n",
    "    :return: \n",
    "    \"\"\"  \n",
    "    dataMat, labelMat = loadDataSet()       #加载数据集，返回数据集合分类  \n",
    "    dataArr = array(dataMat)        #将数据集数组化  \n",
    "    dataShape = shape(dataArr)      #data的形状  \n",
    "    print(\"data的形状：\", dataShape) # (100,3)\n",
    "    n = dataShape[0]        #形状的第一个是行数（即数据集的个数），第二个是列数（即数据集的特征）  \n",
    "    xcord1 = []     #分类为1的点  \n",
    "    ycord1 = []  \n",
    "    xcord0 = []     #分类为0的点  \n",
    "    ycord0 = []  \n",
    "    for i in range(n):  \n",
    "        if int(labelMat[i]) == 1:       #如果分类为1，添加到1分类的点集，否者返回到0分类的点集  \n",
    "            xcord1.append(dataArr[i, 1])        #这个dataArr有3列，其中第0列为1，第1,2列为x，y  \n",
    "            ycord1.append(dataArr[i, 2])  \n",
    "        else:  \n",
    "            xcord0.append(dataArr[i, 1])  \n",
    "            ycord0.append(dataArr[i, 2])  \n",
    "    fig = plt.figure()      #figure()函数创建一个新的图  \n",
    "    ax = fig.add_subplot(111)       #add_subplot()函数在一张figure里面生成多张子图参数111，表示1行1列第1个位置  \n",
    "    ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')       #散点图  \n",
    "    ax.scatter(xcord0, ycord0, s=30, c='green')  \n",
    "    # 直线 x 的范围  \n",
    "    x = arange(-3.0, 3.0, 0.1)      # (start, end, step)可以调step执行起来，看看图  \n",
    "    # 画出直线，weights[0]*1.0+weights[1]*x+weights[2]*y=0  \n",
    "    # 之前计算时对原始数据做了拓展，将两维拓展为三维，第一维全部设置为1.0，实际他是一个 y=ax+b, b常量  \n",
    "    y = (-weights[0]-weights[1]*x)/weights[2]  \n",
    "    ax.plot(x, y)       #画出直线  \n",
    "    plt.xlabel('x1')        #X轴标记为x1  \n",
    "    plt.ylabel('x0')        #Y轴标记为x0  \n",
    "    plt.show()  \n",
    "\"\"\" \n",
    "如果是矩阵的话会报这样的错： \n",
    "\"have shapes {} and {}\".format(x.shape, y.shape)) \n",
    "ValueError: x and y must have same first dimension, but have shapes (60,) and (1, 60) \n",
    "为啥要用数组呢？因为 x = arange(-3.0, 3.0, 0.1)，len(x) = [3-(-3)]/0.1 = 60 \n",
    "而weights是矩阵的话，y = (-weights[0]-weights[1]*x)/weights[2]，len(y) = 1，有60个x，y只有一个，你这样都画不了线 \n",
    "而weights是数据的话，len(y) = 60 \n",
    "\"\"\"  \n",
    "plotBestFit(weights.getA())  #getA()将weights矩阵转换为数组，getA()函数与mat()函数的功能相反  \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "#  以下是随机梯度算法的实现代码：\n",
    "def stocGradAscent0(dataMatrix, classLabels):\n",
    "    m,n = shape(dataMatrix)\n",
    "    alpha = 0.01\n",
    "    weights = ones(n)   #initialize to all ones\n",
    "    for i in range(m):\n",
    "        # h,error全是数值，没有矩阵转换过程。\n",
    "        h = sigmoid(sum(dataMatrix[i]*weights))\n",
    "        error = classLabels[i] - h\n",
    "        weights = weights + alpha * error * dataMatrix[i]\n",
    "    return weights"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "def stocGradAscent1(dataMatrix, classLabels, numIter=150):\n",
    "    m,n = shape(dataMatrix)\n",
    "    weights = ones(n)   #initialize to all ones\n",
    "    for j in range(numIter):\n",
    "        dataIndex = list(range(m))\n",
    "        for i in range(m):\n",
    "            alpha = 4/(1.0+j+i)+0.0001  # alpha在每次迭代时都会调整  \n",
    "            randIndex = int(random.uniform(0,len(dataIndex)))# 随机抽取样本来更改取样样本，减少周期性的波动\n",
    "            h = sigmoid(sum(dataMatrix[randIndex]*weights))\n",
    "            error = classLabels[randIndex] - h\n",
    "#             print(randIndex)\n",
    "            weights = weights + alpha * error * dataMatrix[randIndex]\n",
    "            del(dataIndex[randIndex])\n",
    "    return weights"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "masked_array(data=[10.06591525,  0.50647654, -1.37494986],\n",
       "             mask=False,\n",
       "       fill_value=1e+20)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "weights=stocGradAscent1(array(dataArr), labelMat, numIter=150)\n",
    "weights"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "data的形状： (100, 3)\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plotBestFit(weights)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#实战"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\need\\anaconda\\envs\\py36\\lib\\site-packages\\ipykernel_launcher.py:19: RuntimeWarning: overflow encountered in exp\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(299, 21)\n",
      "the error rate of this test is: 0.328358\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "0.3283582089552239"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def classifyVector(inX, weights):\n",
    "    prob = sigmoid(sum(inX*weights))\n",
    "    if prob > 0.5:\n",
    "        return 1.0\n",
    "    else:\n",
    "        return 0.0\n",
    "    \n",
    "def colicTest():\n",
    "    frTrain = open('horseColicTraining.txt'); frTest = open('horseColicTest.txt')\n",
    "    trainingSet = []; trainingLabels = []\n",
    "    for line in frTrain.readlines():\n",
    "        currLine = line.strip().split('\\t')\n",
    "        lineArr =[]\n",
    "        for i in range(21):\n",
    "            lineArr.append(float(currLine[i]))\n",
    "        trainingSet.append(lineArr)\n",
    "        trainingLabels.append(float(currLine[21]))\n",
    "    trainWeights = stocGradAscent1(array(trainingSet), trainingLabels, 100)\n",
    "    print(array(trainingSet).shape)\n",
    "    errorCount = 0; numTestVec = 0.0\n",
    "    for line in frTest.readlines():\n",
    "        numTestVec += 1.0\n",
    "        currLine = line.strip().split('\\t')\n",
    "        lineArr =[]\n",
    "        for i in range(21):\n",
    "            lineArr.append(float(currLine[i]))\n",
    "        if int(classifyVector(array(lineArr), trainWeights))!= int(currLine[21]):\n",
    "            errorCount += 1\n",
    "    \n",
    "    errorRate = (float(errorCount)/numTestVec)\n",
    "    print (\"the error rate of this test is: %f\" % errorRate)\n",
    "    return errorRate\n",
    "colicTest()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "def multiTest():\n",
    "    numTests = 10\n",
    "    errorSum = 0.0\n",
    "    for k in range(numTests):\n",
    "        errorSum += colicTest()\n",
    "    print('after %d iterations the average error rate is: %f' % (numTests, errorSum/float(numTests)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\need\\anaconda\\envs\\py36\\lib\\site-packages\\ipykernel_launcher.py:19: RuntimeWarning: overflow encountered in exp\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "the error rate of this test is: 0.402985\n",
      "the error rate of this test is: 0.268657\n",
      "the error rate of this test is: 0.358209\n",
      "the error rate of this test is: 0.298507\n",
      "the error rate of this test is: 0.343284\n",
      "the error rate of this test is: 0.373134\n",
      "the error rate of this test is: 0.358209\n",
      "the error rate of this test is: 0.417910\n",
      "the error rate of this test is: 0.298507\n",
      "the error rate of this test is: 0.373134\n",
      "after 10 iterations the average error rate is: 0.349254\n"
     ]
    }
   ],
   "source": [
    "multiTest()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
